#include"list.h"
#include<string.h>
#include<time.h>
#include<stdlib.h>
//创建节点

Node* create_node(void* p)
{
	Node* node = malloc(sizeof(Node));
	node->ptr = p;
	node->next = NULL;
	return node;
}

//创建链表

List* create_list(void)
{
	List* list = malloc(sizeof(List));
	list->head = NULL;
	list->tail = NULL;
	list->size = 0;
	return list;
}

//删除链表

void destory_list(List* list)
{
	Node* prev = list->head;
	while(NULL != prev->next)
	{
		Node* temp = prev;
		prev = prev->next;
		free(temp->ptr);
		free(temp);
	}
	free(prev);
	free(list);
}
//头添加
void add_head(List* list,void* p)
{
	Node* node = create_node(p);
	if(list->size == 0)
	{
		list->head = node;
		list->tail = node;
		list->size++;
		return ;
	}
	node->next = list->head;
	list->head = node;
	list->size++;
}
//尾添加
void add_tail(List* list,void* p)
{
	Node* node = create_node(p);
	if(list->size == 0)
	{
		list->head = node;
		list->tail = node;
		list->size++;
		return ;
	}
	list->tail->next = node;
	list->tail = node;
	list->size++;
}
//头删除
bool del_head(List* list)
{
	if(list->size == 0) return false;
	Node* node = list->head;
	if(list->size == 1)
	{
		list->head = NULL;
		list->tail = NULL;
		free(node->ptr);
		free(node);
		list->size--;
		return true;
	}
	list->head = list->head->next;
	free(node->ptr);
	free(node);
	list->size--;
	return true;
}


//尾删除
bool del_tail(List* list)
{
	if(list->size == 0) return false;
	Node* node = list->head;
	if(list->size == 1)
	{
		list->head = NULL;
		list->tail = NULL;
		free(node->ptr);
		free(node);
		list->size--;
		return true;
	}
	while(node->next->next != NULL) 
	{
		node = node->next;
	}
	Node* node2 = list->tail;
	list->tail = node;
//	list->tail->next = NULL;
	node->next = NULL;
	free(node2->ptr);
	free(node2);
	list->size--;
	return true;

}
//删除

bool del_node(List* list,void* p,Cmpfp func)
{
//	printf("%d\n",func(list->head->ptr,p));

	if(func(list->head->ptr,p) == 0) return del_head(list); 
	if(func(list->tail->ptr,p) == 0) return del_tail(list);
	Node* prev = list->head;
	Node* node = prev->next;
	while(func(node->ptr,p) != 0)
	{
		prev = node;
		node = node->next;
	}
	prev->next = node->next;
	free(node->ptr);
	free(node);
	list->size--;
	return true;
}
//修改

bool modify_node(List* list,void* old,void* p,Cmpfp func)
{
	for(Node* node = list->head;node!=NULL;node = node->next)
	{
		if(0 == func(node->ptr,old))
		{
		//	printf("I find target\n");
			free(node->ptr);
			node->ptr = p;
			return true;
		}
	}
	return false;
}
//查询
Node* find_node(List* list,void* p,Cmpfp func)
{
	for(Node* node = list->head;node!=NULL;node = node->next)
	{
		if(0 == func(node->ptr,p))
		{
		//	printf("I find target\n");
			return node;
		}
	}
	return NULL;
	
}
//遍历

void show(List* list,void(*func)(void* ptr))
{
	for(Node* node = list->head;node != NULL;node = node->next)
	{
		func(node->ptr);
	}
}
//排序(冒泡)
void sort(List* list,Cmpfp func)
{
	if(list->size == 1 || list->size == 0 ) return ;
	for(int i=0;i<list->size;i++)
	{
		for(Node* node = list->head;node->next!=NULL;node = node->next)
		{
			if(1 == func(node->ptr,node->next->ptr))
			{
				void* p = node->ptr;
				node->ptr  = node->next->ptr;
				node->next->ptr = p;
			}
		}
	}
}

/* 测试代码
int main()
{
	srand(time(NULL));
	typedef struct Student
	{
		char name[20];
		char sex;
		int id;
	}Student;
	
    int compare_stu(void*p1, void*p2)
	{
		Student* stu1 = p1;
		Student* stu2 = p2;
		if(stu1->id > stu2->id) return 1;
		else if(stu1->id < stu2->id) return -1;
		else return 0;
	}
	void printf_stu(void* p)
	{
		Student* stu = p;
		printf("%s %c %d\n",stu->name,stu->sex,stu->id);
	}
	List* list  = create_list();
	for(int i=0;i<10;i++)
	{
		Student* stu = malloc(sizeof(Student));
		strcpy(stu->name,"haha");
		stu->sex = 'm';
		stu->id = 1000+rand()%100;
		add_tail(list,stu);
	}
	Student* stu1 = malloc(sizeof(Student));
	strcpy(stu1->name,"haha");
	stu1->sex = 'm';
	stu1->id = 1009;

	Student* stu2 = malloc(sizeof(Student));
	strcpy(stu2->name,"xixi");
	stu2->sex = 'w';
	stu2->id = 1010;
	show(list,printf_stu);
	printf("===============\n");
	sort(list,compare_stu);
	show(list,printf_stu);
}
*/
